/*	Interactive Gravitational Simulator
	Project: IGS Visualization
	File: FontEngine.h
	Author: Mike Bantegui <mbante2@gmail.com>, Hofstra University 
	Copyright (C) 2012 - 2013 Mike Bantegui

	This file is part of the IGS software package for simulating
	the N-Body problem in real-time. This was developed as part
	of a departmental honors thesis project at Hofstra University
	in the Spring 2012 semester.

	IGS is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	IGS is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/* 
	Note: The following font engine implementation has been inspired
	by the font rendering engine within Gravit written by Gerald
	Kaszuba et al. The Gravit implementation may be found at either
	the github repository https://github.com/gak/gravit or on the
	gravit homepage http://gravit.slowchop.com/
*/


#ifndef IGS_FONTENGINE_H
#define IGS_FONTENGINE_H

#include <sstream>
#include <string>

struct SDL_Surface;

namespace IGS
{

// Dictates whether to render a given
// word with left or right alignment
enum TextAlignment
{
	AlignLeft,
	AlignRight
};

// Provides functionality to render textual information on the screen.
// Note: Before LoadFont is called, you must already have a valid OpenGL
// context available. Otherwise, LoadFont will fail.
class FontEngine
{
private:
	struct Letter
	{
		// The texture ID of this letter
		unsigned id;
		// The width of the letter
		int Width;
		// The height of the letter
		int Height;
		// The size of the bounding square of the letter
		int Size;

		Letter();
		Letter(int width, int height);
		void BindTexture(SDL_Surface *surface);
		void FreeTexture();
		int Render(double x, double y);
		bool PreRender(SDL_Surface *rendered);
	};

	// The set of letters available
	Letter Letters[256];
	// The maximal height of a letter in pixels
	int _FontHeight;
	// Whether the engine is in a valid state
	bool IsValid;

public:
	FontEngine();

	bool LoadFont(const char *filename, int size);

	void Render(double x, double y, std::string word);
	void Render(double x, double y, std::string word, TextAlignment align);
	int WordWidth(std::string word);
	int WordWidth(std::string word, int n);

	int FontHeight() const;

private:
	int RenderInner(double x, double y, char letter);
};

// Converts data of type T to a string representation
template <class T>
std::string ToString(const T &object)
{
	std::ostringstream stream;
	stream << object;
	return stream.str();
}

}

#endif